package com.lst.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lst.api.config.SecretConfig;
import com.lst.api.constant.StatusEnum;
import com.lst.api.entity.SysUser;
import com.lst.api.exception.EncryptErrorException;
import com.lst.api.mapper.SysUserMapper;
import com.lst.api.service.ISysUserService;
import com.lst.api.utils.TokenUtil;
import com.lst.api.vo.AccessTokenVo;
import com.lst.api.vo.response.UserLoginResponse;
import com.lst.tools.basics.utils.EncryptUtils;
import com.lst.tools.basics.utils.RandomUtils;
import com.lst.tools.custom.constants.TokenConstants;
import com.lst.tools.mybatis.service.impl.BaseService;
import com.lst.tools.redis.service.IRedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 系统用户业务层实现
 *
 * @author Frank
 * @date 2019-12-30 15:36:39
 * @version: V1.0
 */
@Service
public class SysUserService extends BaseService<SysUserMapper, SysUser> implements ISysUserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SysUserService.class);

    @Autowired
    private TokenUtil tokenUtil;
    @Autowired
    private SecretConfig secretConfig;
    @Autowired
    private IRedisService redisService;

    @Override
    public SysUser getValidByUserNameAndPwd(String userName, String password) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SysUser.USERNAME, userName)
                .eq(SysUser.PASSWORD, EncryptUtils.getSHA256Str(password))
                .eq(SysUser.STATUS, StatusEnum.NORMAL.getKey());
        return super.getOne(queryWrapper);
    }

    @Override
    public UserLoginResponse login(SysUser sysUser, String ip, String tokenRedisKey) {
        AccessTokenVo accessTokenVo = this.generateToken(sysUser, tokenRedisKey);
        redisService.setEx(tokenRedisKey, secretConfig.getAccessTokenExpire(), JSON.toJSONString(accessTokenVo));
        return new UserLoginResponse(sysUser, accessTokenVo);
    }

    private AccessTokenVo generateToken(SysUser sysUser, String tokenRedisKey) {
        try {
            Map<String, Object> claims = new HashMap<String, Object>();
            Long userId = sysUser.getUserId();
            if (userId != null) {
                claims.put(TokenConstants.USER_ID_KEY, userId);
            }
            claims.put(TokenConstants.USER_TOKEN_REDIS_KEY, tokenRedisKey);
            String accessToken = tokenUtil.generateToken(claims);

            claims.remove(TokenConstants.USER_ID_KEY);
            String nonceStr = RandomUtils.createNonceStr();
            claims.put(TokenConstants.SCOPE_KEY, TokenConstants.TICKET);
            claims.put(TokenConstants.TICKET_RANDOM_KEY, nonceStr);
            String ticket = tokenUtil.generateTicket(claims);
            return new AccessTokenVo(ticket, secretConfig.getAccessTokenExpire(), accessToken, nonceStr);
        } catch (Exception e) {
            throw new EncryptErrorException("生成token异常，请重试！");
        }
    }
}